<template>
  <div>
    <el-row v-if="showTool || btnItems.length" :gutter="10" class="mb-8">
      <!-- 操作按钮 -->
      <template v-if="btnItems.length">
        <el-col v-for="items in btnItems" :key="items.key" :span="1.5">
          <el-button
            v-hasPermi="items.permi"
            v-bind="bindProps(items)"
            @click="
              () => {
                btnClick(items)
                items.events && items.events.click(isMultiple ? selection : isRadio ? currentRow : null)
              }
            "
          >
            {{ items.label }}
          </el-button>
        </el-col>
      </template>

      <!-- 工具栏 -->
      <div v-if="showTool" class="top-right-btn mr-5">
        <el-row>
          <el-tooltip class="item" effect="dark" :content="showSearch ? '隐藏搜索' : '显示搜索'" placement="top">
            <el-button circle icon="el-icon-search" @click="$emit('update:showSearch', !showSearch)" />
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="刷新数据" placement="top">
            <el-button circle icon="el-icon-refresh" @click="$emit('refreshTable')" />
          </el-tooltip>
          <el-tooltip v-if="Object.keys(columns).length" class="item" effect="dark" content="筛选字段" placement="top">
            <el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px">
              <el-button circle icon="el-icon-menu" />
              <el-dropdown-menu slot="dropdown">
                <template v-for="item in columns">
                  <el-dropdown-item :key="item.key">
                    <el-checkbox :checked="item.visible" :label="item.label" @change="e => (columns[item.key].visible = e)" />
                  </el-dropdown-item>
                </template>
              </el-dropdown-menu>
            </el-dropdown>
          </el-tooltip>
        </el-row>
      </div>
    </el-row>

    <!-- 表格 -->
    <el-table
      ref="table"
      v-loading="loading"
      :data="tableData"
      :stripe="stripe"
      :border="border"
      :show-header="showHeader"
      height="100%"
      :row-key="rowKey"
      @row-click="rowClick"
      @selection-change="selectionChange"
      @sort-change="$emit('sortChange', $event)"
    >
      <!-- 多选 -->
      <el-table-column
        v-if="isMultiple"
        :reserve-selection="true"
        type="selection"
        width="55"
        align="center"
        :fixed="fixedSelection"
      />

      <!-- 单选 -->
      <el-table-column v-if="isRadio" width="55" align="center" :fixed="fixedSelection">
        <template slot-scope="scope">
          <el-radio v-model="radio" :label="scope.row[rowKey]" @change.native="radioChange(scope.row)" />
        </template>
      </el-table-column>

      <!-- 序号 -->
      <el-table-column
        v-if="isIndex"
        label="序号"
        type="index"
        width="55"
        align="center"
        :index="index => query.pageSize * (query.pageNum - 1) + index + 1"
        :fixed="fixedIndex"
      />

      <!-- 拖拽排序 -->
      <el-table-column v-if="isSort" label="排序" width="55" class-name="allowDrag" align="center" :fixed="fixedSort">
        <el-button type="text" class="el-icon-d-caret !cursor-move" />
      </el-table-column>

      <slot />
    </el-table>

    <!-- 分页 -->
    <pagination
      v-show="total && showPagination"
      :total="total"
      :page.sync="query.pageNum"
      :limit.sync="query.pageSize"
      @pagination="getList"
    />

    <!-- 文件导入弹窗 -->
    <FileImport ref="fileImport" />
  </div>
</template>

<script>
import Sortable from 'sortablejs'

export default {
  props: {
    btnItems: { type: Array, default: () => [] }, // 操作按钮

    loadData: { type: Function, default: () => {} }, // 加载数据的方法

    rowKey: { type: String, default: 'id' }, // 行数据的唯一标识
    isMultiple: { type: Boolean, default: false }, // 是否多选
    isRadio: { type: Boolean, default: false }, // 是否单选
    fixedSelection: { type: Boolean, default: false }, // 固定选择
    isIndex: { type: Boolean, default: true }, // 是否显示序号
    fixedIndex: { type: Boolean, default: false }, // 固定序号
    isSort: { type: Boolean, default: false }, // 是否显示排序
    fixedSort: { type: Boolean, default: false }, // 固定排序
    showPagination: { type: Boolean, default: true }, // 是否显示分页
    border: { type: Boolean, default: true }, // 是否显示边框
    stripe: { type: Boolean, default: true }, // 是否斑马纹
    showHeader: { type: Boolean, default: true }, // 是否显示表头

    columns: { type: Object, default: () => ({}) }, // 筛选列表字段

    showSearch: { type: Boolean, default: true }, // 是否显示搜索框
    showTool: { type: Boolean, default: true } // 是否显示工具栏
  },
  data() {
    return {
      loading: true,
      tableData: [],
      total: 0,
      query: {
        pageNum: 1,
        pageSize: 20
      },
      currentRow: {},
      selection: [],
      radio: ''
    }
  },

  mounted() {
    if (this.isSort) {
      const el = this.$refs.table?.$el?.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
      Sortable.create(el, {
        handle: '.allowDrag',
        onEnd: evt => {
          const targetRow = this.tableData?.splice(evt.oldIndex, 1)[0]
          this.tableData?.splice(evt.newIndex, 0, targetRow)
          for (const index in this.tableData) {
            this.tableData[index].sort = parseInt(index) + 1
          }
        }
      })
    }
  },

  methods: {
    // 绑定属性
    bindProps(val) {
      const obj = val ? JSON.parse(JSON.stringify(val)) : {}
      // 移除冗余属性
      delete obj.label
      delete obj.permi
      delete obj.key
      delete obj.events
      delete obj.upload
      return obj
    },

    getList() {
      this.loading = true
      // prettier-ignore
      this.loadData(this.query).then(res => {
        // console.log('数据', res)
        this.tableData = res?.list || []
        this.total = res?.total || 0
      }).finally(() => (this.loading = false))
    },

    rowClick(val) {
      this.currentRow = val
      this.$emit('rowClick', val)
    },

    selectionChange(val) {
      // console.log('选择', val)
      this.selection = val
      this.btnItems?.forEach(item => {
        item.key === 'onDelete' && (item.disabled = Boolean(val.length <= 0))
        item.key === 'onUpdate' && (item.disabled = Boolean(val.length !== 1))
      })
      this.$emit('select', val)
    },

    radioChange(val) {
      this.btnItems?.forEach(item => {
        item.key === 'onDelete' && (item.disabled = false)
        item.key === 'onUpdate' && (item.disabled = false)
      })
      this.$emit('select', val)
    },

    // 文件导入
    btnClick(val) {
      if (val?.key === 'onImport') {
        Object.assign(this.$refs.fileImport.upload, val?.upload)
      }
      this.$emit(val.key)
    },
    clearSelection() {
      this.$refs.table.clearSelection()
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep .el-radio {
  .el-radio__label {
    display: none !important;
  }
}
::v-deep .el-transfer__button {
  border-radius: 50%;
  padding: 12px;
  display: block;
  margin-left: 0px;
}
::v-deep .el-transfer__button:first-child {
  margin-bottom: 10px;
}
</style>
